// @ts-check
import React , { useReducer, useContext, useEffect, useState, memo, useCallback } from 'react'
import { PlayState } from '@/components/Player/enums'
import * as Reducers from '@/components/Player/store/reducers'
import immer from 'immer'
import mockData from '../api/mockData'
const reducerNameList = Object.keys(Reducers)
// 自动生成action
/**
 * @type { Partial<import('../types').Actions> } }
 * */
const actions = {}
reducerNameList.forEach(reducerName => {
  actions[reducerName] = function (...payload) {
    const pl = payload.length <= 1 ? payload[0] : payload
    return {
      type: reducerName,
      payload: pl
    }
  }
})
   
/** @type { React.Context<import('../types').PlayerStoreContext> } */
export const PlayerStoreContext = React.createContext(null)


/**
 * 类useDispatch
 * @returns { (action?: Partial<import('../types').ActionReturn>) => void }
 */
export const usePlayerStoreDispatch = () => {
  const { dispatch } = useContext(PlayerStoreContext)
  return dispatch
}

/**
 * 类useSelector
 * @template { any } Selected
 * @param {(state: import('../types').PlayerState) => Selected} filter
 * @return { Selected }
 */
export const usePlayerStateSelector = (filter) => {
  const { state } = useContext(PlayerStoreContext)

  return filter(state)
}


export const PlayerStoreProvider = ({
  children
}) => {
  const [PlayerState, PlayerStateDispatch] = useReducer((/** @type {import('../types').PlayerState} */ state, /** @type {{ type: string; payload: any; }} */ action) => {
    if(action) {
      const find = reducerNameList.find(i => i === action.type)
      if(find) {
        return immer(state, (draft) => {
          return Reducers[find](draft, action.payload)
        })
      }
    }
    return state
  }, {
    playState: PlayState.end,
    musicId: 0,
    audioInstance: null,
    // playList: []
    playList: mockData
    // playList: mockData
  })

  return <PlayerStoreContext.Provider value = {{
    state: PlayerState,
    dispatch: PlayerStateDispatch
  }}>{children}</PlayerStoreContext.Provider>
}

// 导出actions
export const {
  changePlayState,
  setMusicId,
  saveAudioInstance,
  replacePlayList,
  pushPlayList,
} = actions
